﻿#include "camerawidget.h"

CameraWidget::CameraWidget(QWidget *parent):
    QWidget(parent)
{
    this->isOpen = false;
    fuTcpServer = FuTcpServer::getTcpServer();
    // 创建控件
    this->cameraComboBox = new QComboBox(this);
    this->cameraShowWidget = new QWidget(this);
    this->cameraLabel = new QLabel(this);
    cameraLabel->setFixedSize(400,300);
    this->openButton = new QPushButton("开启摄像头", this); // 添加按钮初始化
    this->screenshotButton = new QPushButton("截图", this); // 添加按钮初始化
    screenshotButton->setEnabled(false); // 初始不可用

    // 创建布局
    QHBoxLayout *mainlayout =  new QHBoxLayout(this);
    QHBoxLayout *hlayout1 = new QHBoxLayout;
    QHBoxLayout *hlayout2 = new QHBoxLayout;
    QVBoxLayout *vlayout1 = new QVBoxLayout;
    QVBoxLayout *vlayout2 = new QVBoxLayout;

    // 添加控件到布局
    vlayout1->addWidget(cameraComboBox);
    vlayout1->addWidget(cameraShowWidget);
    hlayout1->addStretch();
    hlayout1->addWidget(openButton);
    hlayout1->addStretch();
    hlayout2->addStretch();
    hlayout2->addWidget(screenshotButton);
    hlayout2->addStretch();
    vlayout2->addStretch();
    vlayout2->addWidget(cameraLabel);
    vlayout2->addStretch();
    vlayout2->addLayout(hlayout1);
    vlayout2->addLayout(hlayout2);
    vlayout2->addStretch();
    mainlayout->addLayout(vlayout1);
    mainlayout->addStretch();
    mainlayout->addLayout(vlayout2);
    mainlayout->addStretch();

    // 设置摄像头显示区域样式
    cameraShowWidget->setStyleSheet("background-color: black;");
    cameraShowWidget->setMinimumSize(640, 480);

    // 连接按钮信号
    connect(openButton, &QPushButton::clicked, this, &CameraWidget::slot_switchCamera);
    connect(screenshotButton, &QPushButton::clicked, this, &CameraWidget::slot_imageCaptured);

    initCamera();
    initImageCapture();
}

void CameraWidget::initCamera()
{
    // 创建取景器
    this->viewFinder = new QCameraViewfinder(cameraShowWidget);
    this->viewFinder->resize(800,600);
    viewFinder->setAspectRatioMode(Qt::KeepAspectRatioByExpanding);

    QCameraInfo info = QCameraInfo::defaultCamera();
    cameraComboBox->addItem(info.description());
    this->curCamera = new QCamera(info, this);
    this->curCamera->setViewfinder(this->viewFinder);
}


void CameraWidget::initImageCapture()
{
    this->imageCapture = new QCameraImageCapture(this->curCamera,this);
    this->connect(imageCapture,SIGNAL(readyForCaptureChanged(bool)),this,SLOT(slot_imageReadyForCapture(bool)));
    this->connect(imageCapture,SIGNAL(imageSaved(int,QString)),this,SLOT(slot_imageSaved(int,QString)));
    this->connect(imageCapture,SIGNAL(imageCaptured(int,QImage)),this,SLOT(slot_imageCapturedAfter(int,QImage)));
}

void CameraWidget::cleanupCamera()
{
    if (curCamera) {
        if (curCamera->state() == QCamera::ActiveState) {
            curCamera->stop();
        }
        curCamera->unload();
        delete curCamera;
        curCamera = nullptr;
    }

    if (imageCapture) {
        delete imageCapture;
        imageCapture = nullptr;
    }

    if (viewFinder) {
        viewFinder->deleteLater();
        viewFinder = nullptr;
    }

    isOpen = false;
}

void CameraWidget::reinitCamera()
{
    cleanupCamera();

    // 重新创建取景器
    this->viewFinder = new QCameraViewfinder(cameraShowWidget);
    this->viewFinder->resize(800,600);
    viewFinder->setAspectRatioMode(Qt::KeepAspectRatioByExpanding);

    // 重新获取摄像头信息
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    if (cameras.isEmpty()) {
        QMessageBox::warning(this, "警告", "未找到可用的摄像头设备");
        return;
    }

    // 使用默认摄像头或第一个可用摄像头
    QCameraInfo info = QCameraInfo::defaultCamera();
    if (!info.isNull()) {
        this->curCamera = new QCamera(info, this);
        this->curCamera->setViewfinder(this->viewFinder);
        initImageCapture();
    }
}

//弹出文件保存对话框选择路径，然后保存截图到指定位置
void CameraWidget::imageCaptureAfter(const QByteArray &ack)
{
    if (!isOpen || !curCamera || !imageCapture) {
        QMessageBox::warning(this, "警告", "摄像头未打开或初始化失败！");
        return;
    }

    // 检查摄像头是否支持截图
    if (!curCamera->isCaptureModeSupported(QCamera::CaptureStillImage)) {
        QMessageBox::warning(this, "警告", "当前摄像头不支持截图功能！");
        return;
    }
    if(ack == "1")
    {
        QString defaultName = "摄像头截图_" +
                QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss") +
                ".jpg";

        // 弹出文件保存对话框
        QString fileName = QFileDialog::getSaveFileName(
                    this,
                    "保存截图",
                    QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/" + defaultName,
                    "图片文件 (*.jpg *.jpeg *.png *.bmp)"
                    );

        // 用户取消操作
        if (fileName.isEmpty()) {
            return;
        }
        // 设置捕获目标文件路径
        imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
        // 执行截图操作并保存到指定文件
        imageCapture->capture(fileName);
    }
    else
    {
        QMessageBox::critical(this,"操作失败","截图失败，请检查设备");
    }
}

void CameraWidget::openCameraAfterOn(const QByteArray &ack)
{
    if (ack == "1") {
        if (!isOpen) {
            // 先清理再重新初始化
            reinitCamera();

            if (curCamera) {
                curCamera->start();
                viewFinder->show();
                this->setStyleSheet(""); // 清除透明设置
                this->isOpen = true;
                openButton->setText("关闭摄像头");
                QMessageBox::information(this, "操作成功", "开启摄像头成功");
            } else {
                QMessageBox::critical(this, "错误", "摄像头初始化失败");
            }
        } else {
            QMessageBox::critical(this, "操作失败", "摄像头已经开启");
        }
    } else if (ack == "0") {
        QMessageBox::critical(this, "操作失败", "控制摄像头失败");
    }
}

void CameraWidget::openCameraAfterOff(const QByteArray &ack)
{
    if (ack == "1") {
        if (isOpen) {
            if (curCamera) {
                curCamera->stop();
                viewFinder->hide();
                cameraShowWidget->setStyleSheet("background-color:black");
                openButton->setText("开启摄像头");
                QMessageBox::information(this, "操作成功", "关闭摄像头成功");
            }
            this->isOpen = false;
        } else {
            QMessageBox::critical(this, "操作失败", "摄像头已经关闭");
        }
    } else if (ack == "0") {
        QMessageBox::critical(this, "操作失败", "控制摄像头失败");
    }
}

void CameraWidget::slot_imageReadyForCapture(bool ready)
{
    screenshotButton->setEnabled(true);
}

void CameraWidget::slot_imageCapturedAfter(int id, const QImage &preview)
{
    QImage image = preview.scaled(cameraLabel->size());
    cameraLabel->setPixmap(QPixmap::fromImage(image));
}

void CameraWidget::slot_imageSaved(int id, const QString &fileName)
{
    QMessageBox::information(this,"信息","保存成功",QMessageBox::Ok);
}

void CameraWidget::slot_switchCamera()
{
    if(fuTcpServer->socket == nullptr)
    {
        QMessageBox::critical(nullptr,"错误","客户端未连接");
        return;
    }
    if(!isOpen){
        QByteArray command = QByteArray::number(Common::openCamera);
        qDebug() << "send command: " + command;
        fuTcpServer->socket->write(command);
    }
    else{
        QByteArray command = QByteArray::number(Common::closeCamera);
        qDebug() << "send command: " + command;
        fuTcpServer->socket->write(command);
    }
}

void CameraWidget::slot_imageCaptured()
{
    if(fuTcpServer->socket == nullptr)
    {
        QMessageBox::critical(nullptr,"错误","客户端未连接");
        return;
    }
    QByteArray command = QByteArray::number(Common::captureImage);
    qDebug() << "send command: " + command;
    fuTcpServer->socket->write(command);

}

CameraWidget::~CameraWidget()
{
    delete viewFinder;
}
